﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Awesomium.Windows.Forms;
using System.Xml.Serialization;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using System.Threading;

using Awesomium.Core;

namespace Winz.FoeBot
{
    public static class Extensions
    {
        public static void Save(this List<MotivationPreference> list)
        {
            TextWriter writer = null;
            string path = Bot.settings.fileMotivationPrefs;
            XmlSerializer ser = new XmlSerializer(typeof(List<MotivationPreference>));
            try
            {
                writer = new StreamWriter(path);
            }
            catch (DirectoryNotFoundException e)
            {
                Directory.CreateDirectory(Path.GetDirectoryName(path));
                writer = new StreamWriter(path);
            }
            finally {
                using (writer)
                {
                    ser.Serialize(writer, list);
                    writer.Close();
                }
            }
        }


        public static List<MotivationPreference> Load(this List<MotivationPreference> list)
        {
            XmlSerializer ser = null;
            try
            {
                ser = new XmlSerializer(typeof(List<MotivationPreference>));
            }
            catch (Exception e)
            {
            }
            TextReader reader = null;
            string path = Bot.settings.fileMotivationPrefs;
            try
            {
                reader = new StreamReader(path);
                list = (List<MotivationPreference>)ser.Deserialize(reader);
                reader.Close();
            }
            catch (FileNotFoundException e)
            {
                list = new List<MotivationPreference>();
            }
            catch (DirectoryNotFoundException e)
            {
                list = new List<MotivationPreference>();
            }

            return list;
        }




        public static void InvokeIfRequired<T>(this T c, Action<T> action)
               where T : Control
        {
            if (c.InvokeRequired)
            {
                c.Invoke(new Action(() => action(c)));
            }
            else
            {
                action(c);
            }
        }

        public static void SetBotMode(this WebControl browser, bool isBotMode)
        {
            browser.InvokeIfRequired(b =>
            {
                if (isBotMode)
                {
                    b.FoeZoomIn(); 
                    
                    b.Dock = DockStyle.None;
                    b.Width = 4000;
                    b.Height = 2000;
                    ((Panel)b.Parent).ScrollToBottom();
                }
                else
                {
                    b.FoeZoomOut(); 
                    b.Dock = DockStyle.Fill;
                    
                }
            });

        }


        public static void FoeZoomIn(this WebControl browser)
        {
            Bitmap bitmap = null;
            browser.LeftClick(580, 15);
            Thread.Sleep(500);

            browser.InvokeIfRequired((b) =>
            {
                try
                {

                    bitmap = new Bitmap(b.Width, b.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
                    Rectangle bitmapRect = new Rectangle(0, 0, b.Width, b.Height);
                    b.DrawToBitmap(bitmap, bitmapRect);
                }
                catch (Exception e)
                {
                    return;
                }
            });

            List<Rectangle> list = bitmap.searchBitmap(Properties.Resources.zin, 0.2f, 6);
            if (list.Count > 0)
            {
                Rectangle btn = list.First();
                browser.LeftClick(btn.X + (btn.Width / 2), btn.Y + (btn.Height / 2));
            }
            Thread.Sleep(200);
            bitmap.Dispose();
        }


        public static void FoeZoomOut(this WebControl browser)
        {
            Bitmap bitmap = null;
            browser.LeftClick(580, 15);
            Thread.Sleep(500);
            
            browser.InvokeIfRequired((b) =>
            {
                try
                {
                    bitmap = new Bitmap(b.Width, b.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
                    Rectangle bitmapRect = new Rectangle(0, 0, b.Width, b.Height);
                    b.DrawToBitmap(bitmap, bitmapRect);
                }
                catch (Exception e)
                {
                    return;
                }
            });

            List<Rectangle> list = bitmap.searchBitmap(Properties.Resources.zout, 0.2f, 6);
            if (list.Count > 0)
            {
                Rectangle btn = list.First();
                browser.LeftClick(btn.X + (btn.Width / 2), btn.Y + (btn.Height / 2));
            }
            Thread.Sleep(200);
            bitmap.Dispose();
            
        }



        public static List<Rectangle> FindPattern(this WebControl browser,Bitmap pattern,int max)
        {
            try
            {
                Bitmap bitmap = new Bitmap(browser.Width, browser.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
                Rectangle bitmapRect = new Rectangle(0, 0, browser.Width, browser.Height);
                browser.InvokeIfRequired((b) => b.DrawToBitmap(bitmap, bitmapRect));
                List<Rectangle> res = bitmap.searchBitmap(pattern, 0.1f, max);
                bitmap.Dispose();
                return res;
            }
            catch (Exception e)
            {
                return new List<Rectangle>();
            }

        }


        public static int MouseHoverRectangles(this WebControl browser, List<Rectangle> list, Point delta)
        {
            
            if (list.Count == 0)
                return 0;
            browser.InvokeIfRequired((ctl) =>{
                IWebView webView = (IWebView)ctl;

                webView.InjectMouseMove(list[0].X + (list[0].Width / 2) + delta.X, list[0].Y + (list[0].Height / 2) + delta.Y);
                
                foreach (Rectangle r in list)
                {
                    webView.InjectMouseMove(r.X + (r.Width / 2) + delta.X, r.Y + (r.Height / 2) + delta.Y);
                    Thread.Sleep(20);
                    webView.InjectMouseDown(Awesomium.Core.MouseButton.Left);
                    Thread.Sleep(20);
                    webView.InjectMouseUp(Awesomium.Core.MouseButton.Left);
                    Thread.Sleep(100);
                }
            });

            return list.Count;
        }


        public static void TakeScreenshot(this WebControl browser) {
            string path;

            Bitmap bitmap = new Bitmap(browser.Width, browser.Height,System.Drawing.Imaging.PixelFormat.Format24bppRgb);
            Rectangle bitmapRect = new Rectangle(0, 0, browser.Width, browser.Height);
            browser.DrawToBitmap(bitmap, bitmapRect);
            
            int i = 1;
            path = Bot.settings.folderScreenShots + @"\screenshot" + i.ToString() + ".bmp";
            while (File.Exists(path))
            {
                i++;
                path = Bot.settings.folderScreenShots + @"\screenshot" + i.ToString() + ".bmp";
            }

            if(!Directory.Exists(Path.GetDirectoryName(path)))
                Directory.CreateDirectory(Path.GetDirectoryName(path));

            bitmap.Save(path);
        }


        public static void ScrollToBottom(this Panel p)
        {
            using (Control c = new Control() { Parent = p, Dock = DockStyle.Bottom })
            {
                p.ScrollControlIntoView(c);
                c.Parent = null;
            }
        }


        public static void LeftClick(this Awesomium.Windows.Forms.WebControl webControl, int x, int y)
        {
            webControl.InvokeIfRequired((ctl) =>
            {
                ((Awesomium.Core.IWebView)ctl)._leftClick(x, y);
            });
            
        }


        private static void _leftClick(this Awesomium.Core.IWebView webView, int x, int y)
        {
            webView.InjectMouseMove(x, y);
            webView.InjectMouseDown(Awesomium.Core.MouseButton.Left);
            Thread.Sleep(50);
            webView.InjectMouseUp(Awesomium.Core.MouseButton.Left);
        }


    }

}
